/*
 * @Author: jingfuu@163.com
 * @Date: 2024-10-12 14:37:12
 * @LastEditTime: 2024-11-22 15:04:45
 * @Description: prisma service
 */
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { ConfigService } from '@nestjs/config';
import { ClsService } from 'nestjs-cls';
import { UserSession } from '../UserSession';
import { Constants } from '../Constants';
import { Util } from '../Util';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  constructor(
    private configService: ConfigService,
    private cls: ClsService,
  ) {
    super();
  }
  async onModuleInit() {
    // 查询拦截
    this.$use(async (params, next) => {
      const deleteIgnoreModals = this.configService
        .get('DELETE_IGNORE_MODAL')
        .split(',');
      const isAddDelFlag = !deleteIgnoreModals.includes(params.model);
      if (
        params.action === 'findFirstOrThrow' ||
        params.action === 'findUniqueOrThrow' ||
        params.action === 'findMany' ||
        params.action === 'count' ||
        params.action === 'findUnique' ||
        params.action === 'findFirst'
      ) {
        if (params.args?.where) {
          if (isAddDelFlag && params.args.where.deleted == undefined) {
            params.args.where['delFlag'] = '0';
          }
        } else {
          if (!params.args) params.args = {};
          if (isAddDelFlag) params.args['where'] = { delFlag: '0' };
        }
      }
      return next(params);
    });

    //删除拦截
    this.$use(async (params, next) => {
      const deleteIgnoreModals = this.configService
        .get('DELETE_IGNORE_MODAL')
        .split(',');
      const isAddDelFlag = !deleteIgnoreModals.includes(params.model);
      // 删除字段添加del_flag = '1'
      if (params.action == 'delete') {
        if (isAddDelFlag) {
          params.action = 'update';
          params.args['data'] = {
            delFlag: '1',
          };
        }
      }
      if (params.action == 'deleteMany') {
        if (isAddDelFlag) {
          params.action = 'updateMany';
          params.args['data'] = {
            delFlag: '1',
          };
        }
      }
      return next(params);
    });

    //更新拦截
    this.$use(async (params, next) => {
      const deleteIgnoreModals = this.configService
        .get('DELETE_IGNORE_MODAL')
        .split(',');
      const isAddDelFlag = !deleteIgnoreModals.includes(params.model);
      const auditIgnoreModals = this.configService
        .get('AUDIT_IGNORE_MODAL')
        .split(',');
      const isAuditFlag = !auditIgnoreModals.includes(params.model);
      // 更新处理
      if (params.action == 'updateMany' || params.action == 'update') {
        if (params.args?.where != undefined) {
          if (isAddDelFlag) params.args.where['delFlag'] = '0';
        } else {
          if (!params.args) params.args = {};
          if (isAddDelFlag) params.args['where'] = { delFlag: '0' };
        }
        if (isAuditFlag) {
          const userSession = this.cls.get<UserSession>(Constants.USER_SESSION);
          params.args.data['updateBy'] = userSession?.user.userName;
          params.args.data['updateTime'] = Util.getCurrentLocalTime();
        }
      }
      return next(params);
    });

    // 插入拦截
    this.$use(async (params, next) => {
      const auditIgnoreModals = this.configService
        .get('AUDIT_IGNORE_MODAL')
        .split(',');
      const isAuditFlag = !auditIgnoreModals.includes(params.model);
      const userSession = this.cls.get<UserSession>(Constants.USER_SESSION);
      if (params.action == 'create') {
        if (isAuditFlag && params.args.data != undefined) {
          params.args.data['createBy'] = userSession?.user.userName;
          params.args.data['createTime'] = Util.getCurrentLocalTime();
        }
      }
      if (
        params.action == 'createManyAndReturn' ||
        params.action == 'createMany'
      ) {
        if (
          isAuditFlag &&
          params.args.data != undefined &&
          params.args.data.length > 0
        ) {
          params.args.data.forEach((item) => {
            item['createBy'] = userSession?.user.userName;
            item['createTime'] = Util.getCurrentLocalTime();
          });
        }
      }
      return next(params);
    });
    await this.$connect();
  }
}
